package org.kazuhiko.rpg.server.net;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.kazuhiko.rpg.server.net.codec.RPGCodecFactory;
import org.kazuhiko.rpg.server.net.packet.Packet;
import org.kazuhiko.rpg.server.task.TaskQueue;
import org.kazuhiko.rpg.server.task.tasks.SessionClosedTask;
import org.kazuhiko.rpg.server.task.tasks.SessionMessageTask;
import org.kazuhiko.rpg.server.task.tasks.SessionOpenedTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SessionHandler extends IoHandlerAdapter
{
	private static final Logger logger = LoggerFactory.getLogger( SessionHandler.class );
	
	/**
	 * when somebody opens the connection with the server this function will be called.
	 * at the moment it doesn't do shit
	 */
	@Override
	public void sessionOpened( IoSession session ) throws Exception
	{
		logger.trace( "Session opened. Queuing for initialization." );
		
		session.getFilterChain().addFirst( "protocol", new ProtocolCodecFilter( new RPGCodecFactory() ) );
		
		TaskQueue.getTaskQueue().push( new SessionOpenedTask( session ) );
	}
	
	/**
	 * When the "client" receives a message from the server this function will be called
	 * at the moment it just shows us the message in the logger
	 */
	@Override
	public void messageReceived( IoSession session, Object message ) throws Exception
	{
		TaskQueue.getTaskQueue().push( new SessionMessageTask( session, ( Packet ) message ) );
	}
	
	/**
	 * When the session ( connection ) is closed when the server this function will be called.
	 */
	@Override
	public void sessionClosed( IoSession session ) throws Exception
	{
		logger.info( "Session closed. Queueing for cleanup." );
		
		TaskQueue.getTaskQueue().push( new SessionClosedTask( session ) );
	}
	
	/**
	 * When a exception is thrown ( when something goes wrong ) this function will be called.
	 * at the moment it just closes the session ( connection )
	 */
	@Override
	public void exceptionCaught( IoSession session, Throwable cause ) throws Exception
	{
		logger.error( "Exception occurred. closing session." );
		session.close( false );
	}
}
